package com.example.sandbox.controller.channel.pay58;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.sandbox.controller.notice.TransferComponent;
import com.example.sandbox.dto.Enum.Currency;
import com.example.sandbox.dto.Enum.Order58payStatus;
import com.example.sandbox.dto.Transfer58MerchantRequest;
import com.example.sandbox.dto.domain.PayOrder;
import com.example.sandbox.dto.domain.TransferOrder;
import com.example.sandbox.mapper.TransferOrderMapper;
import com.example.sandbox.util.AmountUtil;
import com.example.sandbox.util.RandomStringGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;

@Slf4j
@RestController
public class Pay58TransferController {

    @Autowired
    private TransferOrderMapper transferOrderMapper;
    @Autowired
    private TransferComponent transferComponent;
    @Autowired
    private Executor generalExecutor;

    @GetMapping("/gateway/v1/sandbox/transfer/simulatePaymentS/{tradeNo}")
    public String simulatePaymentS(@PathVariable("tradeNo") String tradeNo) throws IOException {
        if (StringUtils.isEmpty(tradeNo)) {
            return "Please enter the order number";
        }
        QueryWrapper<TransferOrder> query = new QueryWrapper<>();
        query.eq("transfer_id", tradeNo).eq("state", PayOrder.STATE_ING);
        TransferOrder transferOrder = transferOrderMapper.selectOne(query);
        if (Objects.isNull(transferOrder)) {
            return "The order does not exist or the order status is not in the payment process";
        }
        transferOrder.setState(PayOrder.STATE_SUCCESS);
        int isUpdated = transferOrderMapper.update(transferOrder, query);
        if (isUpdated > 0) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("createdAt", transferOrder.getCreatedAt().getTime()); // 订单创建时间, 13位时间戳
            dataMap.put("amount", AmountUtil.convertCent2Dollar(transferOrder.getAmount(), Currency.BRL.getCurrency())); // 支付金额（3位小数）
            dataMap.put("tradeNo", transferOrder.getMchOrderNo()); // 商户传入的订单号
            dataMap.put("remittanceInformation", transferOrder.getTransferDesc()); // 备注信息
            dataMap.put("endToEndId", "E" + RandomStringGenerator.generateRandomString()); //  E2E订单号
            dataMap.put("clientRequestId", transferOrder.getMchNo()); // 商户号
            dataMap.put("accountNo", transferOrder.getAccountNo()); // 账户编号pixKey
            dataMap.put("successTime", System.currentTimeMillis()); // 订单支付成功时间, 13位时间戳
            dataMap.put("sign", ""); // 订单支付成功时间, 13位时间戳
            dataMap.put("state", Order58payStatus.getValueByKey(PayOrder.STATE_SUCCESS)); // 支付订单状态
            dataMap.put("reqTime", System.currentTimeMillis()); // 订单支付成功时间, 13位时间戳
            dataMap.put("merchantNo", transferOrder.getTransferId()); // 系统支付订单号
            dataMap.put("errCode", null);
            dataMap.put("errMsg", null);
            generalExecutor.execute(() -> {
                try {
                    transferComponent.notifyPaymentPay(dataMap, transferOrder.getNotifyUrl());
                } catch (IOException e) {
                    log.error("58 - 代付成功通知异常 url:{}", transferOrder.getNotifyUrl());
                    throw new RuntimeException(e);
                }
            });
            return "SUCCESS";
        }
        return "FAIL";
    }

    @GetMapping("/gateway/v1/sandbox/transfer/simulatePaymentF/{tradeNo}")
    public String simulatePaymentF(@PathVariable("tradeNo") String tradeNo) throws IOException {
        if (StringUtils.isEmpty(tradeNo)) {
            return "Please enter the order number";
        }
        QueryWrapper<TransferOrder> query = new QueryWrapper<>();
        query.eq("transfer_id", tradeNo).eq("state", PayOrder.STATE_ING);
        TransferOrder transferOrder = transferOrderMapper.selectOne(query);
        if (Objects.isNull(transferOrder)) {
            return "The order does not exist or the order status is not in the payment process";
        }
        transferOrder.setState(PayOrder.STATE_FAIL);
        int isUpdated = transferOrderMapper.update(transferOrder, query);
        if (isUpdated > 0) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("createdAt", transferOrder.getCreatedAt().getTime()); // 订单创建时间, 13位时间戳
            dataMap.put("amount", AmountUtil.convertCent2Dollar(transferOrder.getAmount(), Currency.BRL.getCurrency())); // 支付金额（3位小数）
            dataMap.put("tradeNo", transferOrder.getMchOrderNo()); // 商户传入的订单号
            dataMap.put("remittanceInformation", transferOrder.getTransferDesc()); // 备注信息
            dataMap.put("endToEndId", "E" + RandomStringGenerator.generateRandomString()); //  E2E订单号
            dataMap.put("clientRequestId", transferOrder.getMchNo()); // 商户号
            dataMap.put("accountNo", transferOrder.getAccountNo()); // 账户编号pixKey
            dataMap.put("successTime", System.currentTimeMillis()); // 订单支付成功时间, 13位时间戳
            dataMap.put("sign", ""); // 订单支付成功时间, 13位时间戳
            dataMap.put("state", Order58payStatus.getValueByKey(PayOrder.STATE_FAIL)); // 支付订单状态
            dataMap.put("reqTime", System.currentTimeMillis()); // 订单支付成功时间, 13位时间戳
            dataMap.put("merchantNo", transferOrder.getTransferId()); // 系统支付订单号
            dataMap.put("errCode", null);
            dataMap.put("errMsg", null);
            generalExecutor.execute(() -> {
                try {
                    transferComponent.notifyPaymentPay(dataMap, transferOrder.getNotifyUrl());
                } catch (IOException e) {
                    log.error("58 - 代付失败通知异常 url:{}", transferOrder.getNotifyUrl());
                    throw new RuntimeException(e);
                }
            });
            return "SUCCESS";
        }
        return "FAIL";
    }

    @PostMapping("/gateway/v1/pay/brazil/cashOut/query")
    public Map queryOrder(@RequestBody Transfer58MerchantRequest request) {
        if (StringUtils.isEmpty(request.getClientRequestId()) && StringUtils.isEmpty(request.getTradeNo())) {
            Map map = new HashMap();
            map.put("msg", "Either tradeNo or clientRequestId must be selected");
            return map;
        }
        String transferId = (request.getTradeNo() != null && !request.getTradeNo().isEmpty()) ? request.getTradeNo() : "";
        String mchOrderNo = (request.getClientRequestId() != null && !request.getClientRequestId().isEmpty()) ? request.getClientRequestId() : "";
        QueryWrapper<TransferOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mch_no", request.getMerchantNo());
        queryWrapper.eq(StringUtils.isNotEmpty(transferId), "transfer_id", transferId);
        queryWrapper.eq(StringUtils.isNotEmpty(mchOrderNo), "mch_order_no", mchOrderNo);
        TransferOrder transferOrder = transferOrderMapper.selectOne(queryWrapper);
        if (Objects.isNull(transferOrder)) {
            Map map = new HashMap();
            map.put("msg", "Order does not exist");
            return map;
        }
        Map<String, Object> responseMap = new HashMap<>();

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("merchantNo", transferOrder.getTransferId()); // 系统支付订单号
        dataMap.put("clientRequestId", transferOrder.getMchNo()); // 商户号
        dataMap.put("tradeNo", transferOrder.getMchOrderNo()); // 商户传入的订单号
        dataMap.put("amount", AmountUtil.convertCent2Dollar(transferOrder.getAmount(), Currency.BRL.getCurrency())); // 支付金额（3位小数）
        dataMap.put("state", Order58payStatus.getValueByKey(transferOrder.getState())); // 支付订单状态
        dataMap.put("accountNo", transferOrder.getAccountNo()); // 账户编号pixKey
        dataMap.put("remittanceInformation", transferOrder.getTransferDesc()); // 备注信息
        dataMap.put("endToEndId", "E" + RandomStringGenerator.generateRandomString()); //  E2E订单号
        dataMap.put("createdAt", transferOrder.getCreatedAt().getTime()); // 订单创建时间, 13位时间戳
        dataMap.put("successTime", System.currentTimeMillis()); // 订单支付成功时间, 13位时间戳
        dataMap.put("errCode", "");
        dataMap.put("errMsg", "");

        responseMap.put("code", 0);
        responseMap.put("msg", "SUCCESS");
        responseMap.put("data", dataMap);
        responseMap.put("sign", "557B1724497D5792813CA573D96A23DB"); // 这里的签名根据实际情况生成

        return responseMap;
    }
}